package com.ujoin.util;

import org.json.simple.JSONObject;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.*;

/**
 * 
 * @author 幽蓝
 *
 */

@SuppressWarnings("serial")
public class JsonUtil extends JSONObject {
	private static final String SUCCESS = "success";
	private static final String ERROR = "error";
	private static final String RESULT = "result";
	private static final String MESSAGE = "message";
	private static final String RECORD = "record";
	private static final String RECORDS = "records";
	
	public JsonUtil setSuccess(){
		this.put(RESULT, SUCCESS);
		return this;
	}
	
	public JsonUtil setError(){
		this.put(RESULT, ERROR);
		return this;
	}
	
	public JsonUtil setMessage(Object ob){
		this.put(MESSAGE, ob);
		return this;
	}
	
	public static JsonUtil getError(){
		JsonUtil jsonOb = new JsonUtil();
		jsonOb.put(RESULT, ERROR);
		return jsonOb;
	}
		
	public static JsonUtil getSuccess(){
		JsonUtil jsonOb = new JsonUtil();
		jsonOb.put(RESULT, SUCCESS);
		return jsonOb;
	}
	

	
	public static JsonUtil setComponentList(List list) {
		JsonUtil json = new JsonUtil();
		List listObject = new ArrayList();
		// for(Object model :list)
		for (Iterator ite = list.iterator(); ite.hasNext();) {
			Object model = ite.next();
			Field[] fields = model.getClass().getDeclaredFields();
			Map map = extractAllFields(model, fields);
			listObject.add(map);
		}
		json.put(RECORDS, listObject);
		return json;
	}

	public static JsonUtil setAllComponentsName(Object model) {
		Field[] fields = model.getClass().getDeclaredFields();
		JsonUtil json = new JsonUtil();
		// List list = new ArrayList();
		Map map = extractAllFields(model, fields);
		// list.add(map);
		json.put(RECORD, map);

		return json;
	}

	private static Map extractAllFields(Object model, Field[] fields) {
		Map map = new HashMap();
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			try {
				getFiled(model, map, field, "");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return map;
	}

	public static JsonUtil setComponentName(Object model, String[] varNames) {
		JsonUtil json = new JsonUtil();
		Map map = new HashMap();
		List list = new ArrayList();

		for (String varName : varNames) {
			try {
				getFiled(model, map, varName, "");
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		list.add(map);
		json.put(RECORDS, list);
		return json;
	}

	private static void getFiled(Object model, Map map, String varName,
			String prefix) throws NoSuchMethodException, SecurityException,
			NoSuchFieldException, IllegalAccessException,
			InvocationTargetException {
		Field field = model.getClass().getDeclaredField(varName);
		getFiled(model, map, field, prefix);
	}

	private static void getFiled(Object model, Map map, Field field,
			String prefix) throws NoSuchMethodException,
			IllegalAccessException, InvocationTargetException {
		String varName = field.getName();
		String varNamem = varName.substring(0, 1).toUpperCase()
				+ varName.substring(1);
		String type = field.getGenericType().toString();
		if (type.equals("class java.lang.String")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			String value = (String) m.invoke(model);
			if (value != null) {
				if ("".equals(prefix)) {
					map.put(varName, value);
				} else {
					map.put(prefix + "." + varName, value);
				}
			}
		} else if (type.equals("class java.lang.Integer")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Integer value = (Integer) m.invoke(model);
			if (value != null) {
				if ("".equals(prefix)) {
					map.put(varName, value);
				} else {
					map.put(prefix + "." + varName, value);
				}
			}
		} else if (type.equals("class java.lang.Short")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Short value = (Short) m.invoke(model);
			if (value != null) {
				if ("".equals(prefix)) {
					map.put(varName, value);
				} else {
					map.put(prefix + "." + varName, value);
				}
			}
		} else if (type.equals("class java.lang.Double")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Double value = (Double) m.invoke(model);
			if (value != null) {
				if ("".equals(prefix)) {
					map.put(varName, value);
				} else {
					map.put(prefix + "." + varName, value);
				}
			}
		} else if (type.equals("class java.lang.Boolean")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Boolean value = (Boolean) m.invoke(model);
			if (value != null) {
				if ("".equals(prefix)) {
					map.put(varName, value);
				} else {
					map.put(prefix + "." + varName, value);
				}
			}
		} else if (type.equals("class java.util.Date")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Date value = (Date) m.invoke(model);
			if (value != null) {
				String valueStr = value.toLocaleString();
				if ("".equals(prefix)) {
					map.put(varName, valueStr);
				} else {
					map.put(prefix + "." + varName, valueStr);
				}
			}
		} else if (type.equals("class java.sql.Time")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Time value = (Time) m.invoke(model);
			if (value != null) {
				String valueStr = value.toString();
				if ("".equals(prefix)) {
					map.put(varName, valueStr);
				} else {
					map.put(prefix + "." + varName, valueStr);
				}
			}
		} else if (type.equals("class java.sql.Timestamp")) {
			Method m = model.getClass().getMethod("get" + varNamem);
			Timestamp value = (Timestamp) m.invoke(model);
			if (value != null) {
				String valueStr = value.toString();
				if ("".equals(prefix)) {
					map.put(varName, valueStr.split(" ")[0]);
				} else {
					map.put(prefix + "." + varName, valueStr.split(" ")[0]);
				}
			}
		} else if (type.endsWith("interface java.util.Set")) {

		} else {
			{
				Method m = model.getClass().getMethod("get" + varNamem);
				Object object = m.invoke(model);
				if (object != null) {
					Field[] fs = object.getClass().getDeclaredFields();
					for (Field f : fs) {
						if ("".equals(prefix)) {
							getFiled(object, map, f, varName);
						} else {
							getFiled(object, map, f, prefix + "." + varName);
						}
					}
				}
			}
		}
	}

}
